<?php

namespace App\Services;

use App\Models\Hall;
use common\enum\MasterLogEnum;
use Illuminate\Support\Facades\DB;
use App\Models\AdminUser;
use Illuminate\Support\Facades\Auth;
use App\Models\AdminUserRole;
use App\Models\AdminPermission;
use App\Models\AdminAccess;
use App\Models\PartnerConfig;
use App\Models\HallPartnerConfig;
use App\Models\Setting;
use App\Models\Agent;
use App\Models\HallConfig;
use App\Models\HallDomain;
use App\Models\WebsiteBase;
use Illuminate\Support\Facades\Log;
use App\Models\AgentMoney;
use App\Models\AgentAuthStatus;
use App\Models\AgentProperty;
use App\Models\AgentBkgeTemplate;
use App\Models\AgentBkgeSetting;
use App\Models\AgentRebetSetting;
use App\Models\AgentRebetTemplate;
use App\Models\UserLevel;
use App\Models\HallMenu;
use App\Models\HallMenuConfig;
use App\Models\WebsiteDocument;
use common\utils\RSACrypt;
use common\utils\SysCode;
use App\Models\SmsConfig;
use App\Models\WebsiteAdvert;
use App\Models\AgentBkgeGlobalSetting;
use App\Models\AgentBkgeFeeSetting;

class HallService
{

    /**
     * 厅主名称列表
     * @return mixed
     */
    public static function hallNameList()
    {
        return Hall::select(['id as hall_id', 'company_name as hall_name'])->get();
    }


    public static function getValidHallIDs()
    {
        return Hall::where(['status' => 1])->pluck('id');
    }

    //根据厅主名获取厅id
    public static function getHallIdByName($name)
    {
        return Hall::where(['company_name' => $name])->pluck('id');
    }

    // 管理员账号是否存在
    public static function adminExist($username)
    {
        return AdminUser::where(['username' => $username])->first() !== null;
    }

    public static function addHall($params)
    {
        $operator = Auth::user();
        DB::beginTransaction();
        try {
            // 厅主基本信息
            $hall = new Hall([
                'company_name' => $params['company_name'],
                'admin_name' => $params['admin_name'],
                'operator_id' => $operator['id'],
                'emergency' => $params['emergency'],
                'emergency_code' => RSACrypt::rsaEncrypt($params['emergency_code']),
                'mobile' => isset($params['mobile']) ? RSACrypt::rsaEncrypt($params['mobile']) : '',
                'wechat' => isset($params['wechat']) ? RSACrypt::rsaEncrypt($params['wechat']) : '',
                'skype' => isset($params['skype']) ? RSACrypt::rsaEncrypt($params['skype']) : '',
                'email' => isset($params['email']) ? RSACrypt::rsaEncrypt($params['email']) : '',
                'remark' => isset($params['remark']) ? $params['remark'] : '',
            ]);
            $hall->save();

            // 权限复制
            self::copyPermission($hall['id']);

            // 管理员
            $adminPassword = salt(8);
            $adminSalt = salt();
            $adminUser = new AdminUser([
                'hall_id' => $hall['id'],
                'username' => $params['admin_name'],
                'password' => password_encrypt($adminPassword, $adminSalt),
                'salt' => $adminSalt,
                'role' => 0,
                'is_master' => true,
            ]);
            $adminUser->save();

            // 更新管理员ID
            $hall['admin_uid'] = $adminUser['id'];
            $hall->save();

            // 生成代理退佣退水模板
            $ids = self::createAgentTmpl($hall['id']);

            // 默认股东
            $shareholderUsername = 'MRGD' . $hall['id'];
            $shareholderPassword = salt(8);
            $shareholderID = self::createDefaultAgent($hall['id'], $ids, $shareholderUsername, $shareholderPassword, 0, 0);

            // 默认代理
            $agentUsername = 'MRDL' . $hall['id'];
            $agentPassword = salt();
            $agentID = self::createDefaultAgent($hall['id'], $ids, $agentUsername, $agentPassword, 1, $shareholderID);

            // 默认用户层级
            UserLevel::insert([
                'hall_id' => $hall['id'],
                'name' => '默认层级',
                'description' => '默认层级',
                'is_default' => true,
            ]);

            // 厅主配置
            $hc = new HallConfig([
                'hall_id' => $hall['id'],
                'default_agent' => $agentID,
                'default_shareholder' => $shareholderID,
                'is_use_googlekey' => $params['is_use_googlekey'],
                'status' => $params['status'],
                'fee_monthly_amount' => 80000000, // 默认包网保底费用 80000元
            ]);
            $hc->save();

            // 游戏API
            $partnerList = PartnerConfig::whereIn('id', $params['partner_list'])->get();
            $insertPartnerConfig = [];
            foreach ($partnerList as $p) {
                $insertPartnerConfig[] = [
                    'hall_id' => $hall['id'],
                    'partner_id' => $p['partner_id'],
                    'partner_name' => $p['partner_name'],
                    'game_type' => $p['game_type'],
                    'status' => 1,
                    'pre_status' => 1,
                ];
            }
            HallPartnerConfig::insert($insertPartnerConfig);

            // 域名
            $insertDomain = [];
            foreach ($params['domains'] as $d) {
                $insertDomain[] = [
                    'hall_id' => $hall['id'],
                    'agent_id' => 0,
                    'agent_name' => '',
                    'domain' => $d,
                ];
            }
            HallDomain::insert($insertDomain);

            // 默认菜单
            self::copyHallMenu($hall['id']);

            // 默认文案
            self::copyWebsiteDocument($hall['id']);

            // 默认广告
            self::copyWebsiteAdvert($hall['id']);

            // 默认配置
            $settingList = Setting::where(['hall_id' => 0])->whereNotIn('key', SettingService::$globalSetting)->get();
            $insertSetting = [];
            foreach ($settingList as $p) {
                $insertSetting[] = [
                    'hall_id' => $hall['id'],
                    'key' => $p['key'],
                    'value' => $p['value'],
                ];
            }
            Setting::insert($insertSetting);

            // 短信配置
            self::copySmsConfig($hall['id']);

            // 网站配置
            $wb = WebsiteBase::where(['hall_id' => 0])->first()->toArray();
            unset($wb['id']);
            $wb['hall_id'] = $hall['id'];
            WebsiteBase::insert($wb);

            DB::commit();
        } catch (\Exception $e) {
            Log::error('Add Hall Error: ' . $e->getTraceAsString(), $params);
            DB::rollBack();
            error_exit(SysCode::INTERNAL_SERVER_ERROR);
        }
        $remark = str_replace('{:name}', $params['admin_name'], MasterLogEnum::REMARK['hall_add']);
        MasterLogService::writeMasterLog(MasterLogEnum::GAME_HALL_ADD, MasterLogEnum::SUCCESS, $remark);
        return [
            'company_name' => $params['company_name'],
            'admin_name' => $params['admin_name'],
            'admin_password' => $adminPassword,
            'domains' => $params['domains'],
            'agent' => $agentUsername,
            'agent_password' => $agentPassword,
            'shareholder' => $shareholderUsername,
            'shareholder_password' => $shareholderPassword,
        ];
    }

    // 权限复制，外层做事务处理，不允许直接调用！！！
    private static function copyPermission($hallID)
    {
        $rolelist = AdminUserRole::where(['hall_id' => 0])->get()->toArray();
        $roleIDs = array_column($rolelist, 'id');
        $accessList = AdminPermission::whereIn('role_id', $roleIDs)->get()->toArray();
        $roleMap = [];

        foreach ($rolelist as $r) {
            $roleID = AdminUserRole::insertGetId([
                'hall_id' => $hallID,
                'role' => $r['role'],
            ]);
            $roleMap[$r['id']] = $roleID;
        }

        foreach ($accessList as &$a) {
            unset($a['id']);
            $a['hall_id'] = $hallID;
            $a['role_id'] = $roleMap[$a['role_id']];
        }
        AdminPermission::insert($accessList);
    }

    // 菜单复制，外层做事务处理，不允许直接调用！！！
    private static function copyHallMenu($hallID)
    {
        $menuList = HallMenu::where(['hall_id' => 0])->get()->toArray();
        $menuIDs = array_column($menuList, 'id');
        $menuConfigList = HallMenuConfig::whereIn('pid', $menuIDs)->get()->toArray();
        $menuMap = [];

        foreach ($menuList as $m) {
            $mid = $m['id'];
            unset($m['id']);
            $m['hall_id'] = $hallID;
            $m['pid'] = $m['pid'] == 0 ? 0 : $menuMap[$mid];
            $menuID = HallMenu::insertGetId($m);
            $menuMap[$mid] = $menuID;
        }

        $insertMenuConfig = [];
        foreach ($menuConfigList as $mc) {
            $mc['pid'] = $menuMap[$mc['pid']];
            $mc['hall_id'] = $hallID;
            unset($mc['id']);
            $insertMenuConfig[] = $mc;
        }
        HallMenuConfig::insert($insertMenuConfig);
    }

    // 文案复制，外层做事务处理，不允许直接调用！！！
    private static function copyWebsiteDocument($hallID)
    {
        $wd = WebsiteDocument::where(['hall_id' => 0])->get()->toArray();
        foreach ($wd as &$d) {
            $d['hall_id'] = $hallID;
            unset($d['id']);
        }
        WebsiteDocument::insert($wd);
    }

    // 轮播图复制，外层做事务处理，不允许直接调用！！！
    private static function copyWebsiteAdvert($hallID)
    {
        $wd = WebsiteAdvert::where(['hall_id' => 0])->get()->toArray();
        foreach ($wd as &$d) {
            $d['hall_id'] = $hallID;
            unset($d['id']);
        }
        WebsiteAdvert::insert($wd);
    }

    // 短信配置复制，外层做事务处理，不允许直接调用！！！
    private static function copySmsConfig($hallID)
    {
        $sc = SmsConfig::where(['hall_id' => 0])->get()->toArray();
        foreach ($sc as &$c) {
            $c['hall_id'] = $hallID;
            unset($c['id']);
        }
        SmsConfig::insert($sc);
    }

    // 生成默认代理账号，外层做事务处理，不允许直接调用！！！
    private static function createDefaultAgent($hallID, $ids, $username, $password, $type, $pid)
    {
        $salt = salt();
        $code = DB::table('agent')->max('code');
        if ($code < 100000) {
            $code = 100000;
        }
        $id = Agent::insertGetId([
            'hall_id' => $hallID,
            'pid' => $pid,
            'type' => $type,
            'level' => 0,
            'agent_name' => $username,
            'password' => password_encrypt($password, $salt),
            'salt' => $salt,
            'code' => $code + 1,
        ]);

        // 代理属性
        AgentProperty::insert([
            'hall_id' => $hallID,
            'agent_id' => $id,
            'bkge_template_id' => $type == 0 ? 0 : $ids[0],
            'rebet_template_id' => $type == 0 ? 0 : $ids[1],
            'show_per' => $type == 0 ? '{"video":0,"esport":0,"sport":0,"egame":0,"card":0,"lottery":0}' : '', // 股东
        ]);

        // 创建代理钱包
        AgentMoney::insert([
            'hall_id' => $hallID,
            'agent_id' => $id
        ]);

        // 代理权限控制
        AgentAuthStatus::insert([
            'agent_id' => $id
        ]);

        return $id;
    }

    // 生成退佣，退水默认模板，外层做事务处理，不允许直接调用！！！
    private static function createAgentTmpl($hallID)
    {
        // 退佣
        $defaultBkgeTmpl = AgentBkgeTemplate::where(['hall_id' => 0])->first()->toArray();
        $defaultBkgeTmplID = $defaultBkgeTmpl['id'];
        $defaultBkgeTmpl['hall_id'] = $hallID;
        unset($defaultBkgeTmpl['id']);
        $abtID = AgentBkgeTemplate::insertGetId($defaultBkgeTmpl);

        $abs = AgentBkgeSetting::where(['hall_id' => 0])->get()->toArray();
        foreach ($abs as &$c) {
            $c['hall_id'] = $hallID;
            $c['template_id'] = $abtID;
            unset($c['id']);
        }
        AgentBkgeSetting::insert($abs);

        // 退水
        $defaultRebetTmpl = AgentRebetTemplate::where(['hall_id' => 0])->first()->toArray();
        $defaultRebetTmplID = $defaultRebetTmpl['id'];
        $defaultRebetTmpl['hall_id'] = $hallID;
        unset($defaultRebetTmpl['id']);
        $artID = AgentRebetTemplate::insertGetId($defaultRebetTmpl);

        $abs = AgentRebetSetting::where(['hall_id' => 0])->get()->toArray();
        foreach ($abs as &$c) {
            $c['hall_id'] = $hallID;
            $c['template_id'] = $artID;
            unset($c['id']);
        }
        AgentRebetSetting::insert($abs);

        // 设置
        $gs = AgentBkgeGlobalSetting::where(['hall_id' => 0])->first()->toArray();
        $gs['hall_id'] = $hallID;
        unset($gs['id']);
        AgentBkgeGlobalSetting::insert($gs);

        $gs = AgentBkgeFeeSetting::where(['hall_id' => 0])->first()->toArray();
        $gs['hall_id'] = $hallID;
        unset($gs['id']);
        AgentBkgeFeeSetting::insert($gs);
        return [$abtID, $artID];
    }
}
